'use client';

import { useState, useEffect, useRef } from 'react';
import GlassCard from '@/components/ui/GlassCard';
import GlassButton from '@/components/ui/GlassButton';
import { MessageSquare, Send, Plus, Trash2, Clock, User, Bot, Copy, Check, BookmarkPlus, X } from 'lucide-react';
import toast from 'react-hot-toast';
import { chatApi, knowledgeBaseApi, notesApi } from '@/lib/api';
import { useAuthStore } from '@/store/authStore';
import { useRouter } from 'next/navigation';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';

interface Message {
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
  sources?: Array<{
    document_id: string;
    document_title: string;
    chunk_index: number;
    similarity: number;
    excerpt: string;
  }>;
}

interface ChatSession {
  id: string;
  title: string;
  knowledge_base_id?: string;
  created_at: string;
  message_count: number;
}

export default function ChatPage() {
  const router = useRouter();
  const { user } = useAuthStore();
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const [knowledgeBases, setKnowledgeBases] = useState<any[]>([]);
  const [selectedKB, setSelectedKB] = useState('llm-only');
  const [selectedKBs, setSelectedKBs] = useState<string[]>([]);
  const [showKBSelector, setShowKBSelector] = useState(false);
  const [documents, setDocuments] = useState<any[]>([]);
  const [selectedDocuments, setSelectedDocuments] = useState<string[]>([]);
  const [showDocSelector, setShowDocSelector] = useState(false);
  const [docSearchQuery, setDocSearchQuery] = useState('');
  const [docFilterKB, setDocFilterKB] = useState<string>('all');
  const [docSelectorExpanded, setDocSelectorExpanded] = useState(true);
  const [temperature, setTemperature] = useState(0.7);
  const [maxTokens, setMaxTokens] = useState(2000);
  
  // 会话历史相关
  const [sessions, setSessions] = useState<ChatSession[]>([]);
  
  // 记笔记相关
  const [showSaveNoteMenu, setShowSaveNoteMenu] = useState<number | null>(null);
  const [myNotes, setMyNotes] = useState<any[]>([]);
  const [savingNote, setSavingNote] = useState(false);
  const [currentSession, setCurrentSession] = useState<ChatSession | null>(null);
  const [showSessions, setShowSessions] = useState(true);
  
  // 输入框引用
  const inputRef = useRef<HTMLTextAreaElement>(null);
  
  // 删除确认对话框
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<{ id: string; title: string } | null>(null);
  
  // 复制功能
  const [copiedIndex, setCopiedIndex] = useState<number | null>(null);
  
  // 参考文档展开状态
  const [expandedSources, setExpandedSources] = useState<Set<number>>(new Set());
  
  const messagesEndRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    loadKnowledgeBases();
    loadSessions();
    loadUserPreferences();
    loadMyNotes();
  }, []);

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  const loadUserPreferences = () => {
    try {
      const saved = localStorage.getItem('user_preferences');
      if (saved) {
        const prefs = JSON.parse(saved);
        if (prefs.temperature) setTemperature(prefs.temperature);
        if (prefs.max_tokens) setMaxTokens(prefs.max_tokens);
      }
    } catch (error) {
      console.error('加载用户偏好失败:', error);
    }
  };

  const loadKnowledgeBases = async () => {
    try {
      const response = await knowledgeBaseApi.list();
      setKnowledgeBases(response.items || []);
    } catch (error: any) {
      console.error('加载知识库失败:', error);
    }
  };

  const loadDocuments = async (kbId?: string) => {
    try {
      const { documentsApi } = await import('@/lib/api');
      const response = await documentsApi.list({
        knowledge_base_id: kbId,
        page: 1,
        page_size: 100,
      });
      const vectorizedDocs = (response.items || []).filter((doc: any) => doc.is_vectorized);
      setDocuments(vectorizedDocs);
    } catch (error: any) {
      console.error('加载文档失败:', error);
    }
  };

  const loadSessions = async () => {
    try {
      const response = await chatApi.getSessions();
      setSessions(response || []);
    } catch (error: any) {
      console.error('加载会话列表失败:', error);
    }
  };

  const createNewSession = async () => {
    try {
      const title = `对话 ${new Date().toLocaleString('zh-CN')}`;
      const session = await chatApi.createSession({
        title,
        knowledge_base_id: selectedKB === 'llm-only' ? undefined : selectedKB
      });
      setSessions([session, ...sessions]);
      setCurrentSession(session);
      setMessages([]);
      toast.success('新建会话成功');
    } catch (error: any) {
      toast.error('创建会话失败: ' + (error.message || '未知错误'));
    }
  };

  const loadSessionMessages = async (session: ChatSession) => {
    try {
      setLoading(true);
      const response = await chatApi.getSessionMessages(session.id);
      const historyMessages = response.map((msg: any) => ({
        role: msg.role,
        content: msg.content,
        timestamp: new Date(msg.created_at),
        sources: msg.metadata?.sources
      }));
      setMessages(historyMessages);
      setCurrentSession(session);
      if (session.knowledge_base_id) {
        setSelectedKB(session.knowledge_base_id);
      }
    } catch (error: any) {
      toast.error('加载消息失败: ' + (error.message || '未知错误'));
    } finally {
      setLoading(false);
    }
  };

  const confirmDeleteSession = (sessionId: string, title: string, e: React.MouseEvent) => {
    e.stopPropagation();
    setDeleteTarget({ id: sessionId, title });
    setShowDeleteConfirm(true);
  };

  const deleteSession = async () => {
    if (!deleteTarget) return;
    
    const { id: sessionId } = deleteTarget;
    setShowDeleteConfirm(false);
    
    try {
      await chatApi.deleteSession(sessionId);
      setSessions(sessions.filter(s => s.id !== sessionId));
      if (currentSession?.id === sessionId) {
        setCurrentSession(null);
        setMessages([]);
      }
      toast.success('删除成功');
    } catch (error: any) {
      toast.error('删除失败: ' + (error.message || '未知错误'));
    }
  };

  const copyToClipboard = async (text: string, index: number) => {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedIndex(index);
      toast.success('已复制到剪贴板');
      setTimeout(() => setCopiedIndex(null), 2000);
    } catch (error) {
      toast.error('复制失败');
    }
  };

  const loadMyNotes = async () => {
    try {
      const notes = await notesApi.list({ limit: 20 });
      setMyNotes(notes);
    } catch (error) {
      console.error('加载笔记列表失败:', error);
    }
  };

  const saveToNewNote = async (message: Message) => {
    try {
      setSavingNote(true);
      const userQuestion = messages[messages.findIndex(m => m === message) - 1]?.content || '问题';
      
      // 提取引用的文档ID
      const docIds = message.sources?.map(s => s.document_id).filter((v, i, a) => a.indexOf(v) === i) || [];
      
      const noteContent = `## 问题\n${userQuestion}\n\n## AI 回答\n${message.content}\n\n## 来源\n${
        message.sources?.map(s => `- ${s.document_title} (相似度: ${(s.similarity * 100).toFixed(1)}%)`).join('\n') || '无'
      }`;
      
      await notesApi.saveFromChat({
        title: userQuestion.substring(0, 50),
        content: noteContent,
        document_ids: docIds,
        metadata: {
          from_chat: true,
          created_at: new Date().toISOString()
        }
      });
      
      toast.success('已保存到新笔记');
      setShowSaveNoteMenu(null);
      loadMyNotes();
    } catch (error: any) {
      toast.error('保存失败: ' + error.message);
    } finally {
      setSavingNote(false);
    }
  };

  const saveToExistingNote = async (message: Message, noteId: string) => {
    try {
      setSavingNote(true);
      const userQuestion = messages[messages.findIndex(m => m === message) - 1]?.content || '问题';
      
      const noteContent = `\n\n---\n\n## 问题 (${new Date().toLocaleString('zh-CN')})\n${userQuestion}\n\n## AI 回答\n${message.content}`;
      
      await notesApi.saveFromChat({
        note_id: noteId,
        title: '', // 不更新标题
        content: noteContent
      });
      
      toast.success('已追加到笔记');
      setShowSaveNoteMenu(null);
    } catch (error: any) {
      toast.error('保存失败: ' + error.message);
    } finally {
      setSavingNote(false);
    }
  };

  const handleSend = async () => {
    if (!input.trim() || loading) return;

    const userMessage: Message = {
      role: 'user',
      content: input.trim(),
      timestamp: new Date(),
    };
    
    setMessages((prev) => [...prev, userMessage]);
    setInput('');
    setLoading(true);

    try {
      const assistantMessage: Message = {
        role: 'assistant',
        content: '',
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, assistantMessage]);

      await chatApi.sendMessageStream(
        userMessage.content,
        (content: string) => {
          // 逐字更新 - 创建新对象而不是修改原对象
          setMessages((prev) => {
            const newMessages = [...prev];
            const lastMessage = newMessages[newMessages.length - 1];
            if (lastMessage && lastMessage.role === 'assistant') {
              // 创建新的 message 对象
              newMessages[newMessages.length - 1] = {
                ...lastMessage,
                content: lastMessage.content + content
              };
            }
            return newMessages;
          });
        },
        (sessionId?: string) => {
          // 完成时更新会话
          if (sessionId && !currentSession) {
            // 更新当前会话 ID，避免下次提问时创建新会话
            setCurrentSession({
              id: sessionId,
              title: userMessage.content.substring(0, 50),
              user_id: '',
              created_at: new Date().toISOString(),
              updated_at: new Date().toISOString(),
              message_count: 2,
              knowledge_base_id: selectedKB === 'llm-only' ? undefined : selectedKB
            });
            loadSessions();
          }
          setLoading(false);
          // 发送完成后，聚焦输入框
          setTimeout(() => inputRef.current?.focus(), 100);
        },
        (error: string) => {
          // 错误处理
          toast.error(`发送失败: ${error}`);
          setLoading(false);
        },
        {
          knowledge_base_id: (() => {
            if (selectedKB === 'llm-only') return undefined;
            if (selectedKB === 'multiple') return selectedKBs.length > 0 ? selectedKBs.join(',') : undefined;
            if (selectedKB === 'documents') {
              // 选择具体文档时，需要传递文档所属的知识库ID
              // 从已选文档中提取知识库ID（假设同一批文档来自同一知识库）
              const selectedDocsData = documents.filter(d => selectedDocuments.includes(d.id));
              const kbIds = [...new Set(selectedDocsData.map(d => d.knowledge_base_id).filter(Boolean))];
              return kbIds.length > 0 ? kbIds.join(',') : undefined;
            }
            return selectedKB;
          })(),
          document_ids: selectedKB === 'documents' && selectedDocuments.length > 0 ? selectedDocuments.join(',') : undefined,
          temperature,
          max_tokens: maxTokens,
          session_id: currentSession?.id,
          onSources: (sources: any[]) => {
            setMessages((prev) => {
              const newMessages = [...prev];
              const lastMessage = newMessages[newMessages.length - 1];
              if (lastMessage && lastMessage.role === 'assistant') {
                // 创建新的 message 对象
                newMessages[newMessages.length - 1] = {
                  ...lastMessage,
                  sources: sources
                };
              }
              return newMessages;
            });
          },
        }
      );

      // 刷新会话列表（消息数+1）
      if (currentSession) {
        loadSessions();
      }
    } catch (error: any) {
      toast.error('发送失败: ' + (error.message || '未知错误'));
      setMessages((prev) => prev.slice(0, -1));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="flex h-[calc(100vh-180px)] gap-4">
      {/* 左侧会话历史 */}
      {showSessions && (
        <div className="w-64 h-full flex-shrink-0">
          <GlassCard className="h-full flex flex-col p-4">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-2">
                <Clock className="h-5 w-5 text-indigo-500" />
                对话历史
              </h2>
              <button
                onClick={createNewSession}
                className="p-2 rounded-lg hover:bg-gray-200/50 dark:hover:bg-white/10 text-indigo-500"
                title="新建对话"
              >
                <Plus className="h-5 w-5" />
              </button>
            </div>

            <div className="flex-1 overflow-y-auto space-y-2">
              {sessions.length === 0 ? (
                <p className="text-sm text-gray-500 dark:text-white/60 text-center py-8">
                  暂无历史对话
                </p>
              ) : (
                sessions.map((session) => (
                  <div
                    key={session.id}
                    onClick={() => loadSessionMessages(session)}
                    className={`p-3 rounded-lg cursor-pointer transition-colors group ${
                      currentSession?.id === session.id
                        ? 'bg-gradient-to-r from-indigo-500/20 to-purple-500/20 border border-indigo-500/30'
                        : 'hover:bg-gray-100 dark:hover:bg-white/10'
                    }`}
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="flex-1 min-w-0">
                        <h3 className="text-sm font-medium text-gray-900 dark:text-white truncate">
                          {session.title}
                        </h3>
                        <p className="text-xs text-gray-500 dark:text-white/60 mt-1">
                          {session.message_count} 条消息
                        </p>
                      </div>
                      <button
                        onClick={(e) => confirmDeleteSession(session.id, session.title, e)}
                        className="opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-red-100 dark:hover:bg-red-500/20 text-red-500 transition-opacity"
                        title="删除"
                      >
                        <Trash2 className="h-4 w-4" />
                      </button>
                    </div>
                  </div>
                ))
              )}
            </div>

            <div className="mt-4 pt-4 border-t border-gray-200/40 dark:border-white/20">
              <GlassButton
                onClick={createNewSession}
                variant="primary"
                size="sm"
                className="w-full"
              >
                <Plus className="mr-2 h-4 w-4" />
                新建对话
              </GlassButton>
            </div>
          </GlassCard>
        </div>
      )}

      {/* 右侧聊天区域 */}
      <div className="flex-1 h-full flex flex-col">
        <GlassCard className="h-full flex flex-col">
          {/* 顶部配置区 */}
          <div className="p-4 border-b border-gray-200/40 dark:border-white/20">
            <div className="flex items-center gap-4">
              <div className="flex-1">
                <label className="block text-sm font-medium text-gray-700 dark:text-white/80 mb-2">
                  知识库
                </label>
                <select
                  value={selectedKB}
                  onChange={(e) => {
                    const value = e.target.value;
                    setSelectedKB(value);
                    if (value === 'multiple') {
                      setShowKBSelector(true);
                      setShowDocSelector(false);
                    } else if (value === 'documents') {
                      setShowDocSelector(true);
                      setShowKBSelector(false);
                      loadDocuments();
                    } else {
                      setShowKBSelector(false);
                      setShowDocSelector(false);
                    }
                  }}
                  className="w-full px-3 py-2 bg-white/60 dark:bg-gray-800 backdrop-blur-md border border-gray-300/40 dark:border-white/20 rounded-lg text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/40 [&>option]:bg-white [&>option]:dark:bg-gray-800 [&>option]:text-gray-900 [&>option]:dark:text-white"
                >
                  <option value="llm-only">仅LLM（不使用知识库）</option>
                  <option value="documents">选择具体文档</option>
                  <option value="multiple">多选知识库</option>
                  {knowledgeBases.map((kb) => (
                    <option key={kb.id} value={kb.id}>
                      {kb.name}
                    </option>
                  ))}
                </select>
              </div>

              <div className="w-32">
                <label className="block text-sm font-medium text-gray-700 dark:text-white/80 mb-2">
                  Temperature
                </label>
                <input
                  type="number"
                  value={temperature}
                  onChange={(e) => setTemperature(parseFloat(e.target.value))}
                  step="0.1"
                  min="0"
                  max="1"
                  className="w-full px-3 py-2 bg-white/60 dark:bg-white/10 backdrop-blur-md border border-gray-300/40 dark:border-white/20 rounded-lg text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-indigo-500/40"
                />
              </div>
            </div>

            {showKBSelector && (
              <div className="mt-4 pt-4 border-t border-gray-200/40 dark:border-white/20">
                <p className="text-sm text-gray-600 dark:text-white/70 mb-2">选择要检索的知识库：</p>
                <div className="grid grid-cols-2 gap-2">
                  {knowledgeBases.map((kb) => (
                    <label
                      key={kb.id}
                      className="flex items-center gap-2 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-white/10 cursor-pointer"
                    >
                      <input
                        type="checkbox"
                        checked={selectedKBs.includes(kb.id)}
                        onChange={(e) => {
                          if (e.target.checked) {
                            setSelectedKBs([...selectedKBs, kb.id]);
                          } else {
                            setSelectedKBs(selectedKBs.filter(id => id !== kb.id));
                          }
                        }}
                        className="w-4 h-4 text-indigo-500 rounded focus:ring-2 focus:ring-indigo-500/40"
                      />
                      <span className="text-sm text-gray-700 dark:text-white/80">{kb.name}</span>
                    </label>
                  ))}
                </div>
                {selectedKBs.length > 0 && (
                  <p className="text-xs text-indigo-500 dark:text-indigo-400 mt-2">
                    已选择 {selectedKBs.length} 个知识库
                  </p>
                )}
              </div>
            )}

            {showDocSelector && (
              <div className="mt-4 pt-4 border-t border-gray-200/40 dark:border-white/20">
                <div className="flex items-center justify-between mb-2">
                  <p className="text-sm text-gray-600 dark:text-white/70">
                    选择要检索的文档（已向量化）：
                    {selectedDocuments.length > 0 && (
                      <span className="ml-2 text-indigo-600 dark:text-indigo-400 font-medium">
                        已选 {selectedDocuments.length} 个
                      </span>
                    )}
                  </p>
                  <button
                    onClick={() => setDocSelectorExpanded(!docSelectorExpanded)}
                    className="text-sm text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors px-2 py-1 rounded hover:bg-indigo-50 dark:hover:bg-indigo-500/10"
                  >
                    {docSelectorExpanded ? '▼ 收起' : '▶ 展开'}
                  </button>
                </div>
                {docSelectorExpanded && (documents.length === 0 ? (
                  <p className="text-sm text-gray-500 dark:text-white/50 text-center py-4">
                    暂无已向量化的文档
                  </p>
                ) : (
                  <>
                    {/* 搜索和筛选 */}
                    <div className="space-y-2 mb-3">
                      <input
                        type="text"
                        placeholder="搜索文档标题..."
                        value={docSearchQuery}
                        onChange={(e) => setDocSearchQuery(e.target.value)}
                        className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-white/20 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500/40"
                      />
                      <select
                        value={docFilterKB}
                        onChange={(e) => setDocFilterKB(e.target.value)}
                        className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-white/20 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500/40"
                      >
                        <option value="all">所有知识库</option>
                        {knowledgeBases.map((kb: any) => (
                          <option key={kb.id} value={kb.id}>{kb.name}</option>
                        ))}
                      </select>
                      {/* 快捷操作 */}
                      <div className="flex gap-2">
                        <button
                          onClick={() => {
                            const filteredDocs = documents.filter((doc: any) => {
                              const matchesSearch = docSearchQuery === '' || doc.title.toLowerCase().includes(docSearchQuery.toLowerCase());
                              const matchesKB = docFilterKB === 'all' || doc.knowledge_base_id === docFilterKB;
                              return matchesSearch && matchesKB;
                            });
                            setSelectedDocuments(filteredDocs.map((d: any) => d.id));
                          }}
                          className="flex-1 px-2 py-1 text-xs bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-600 dark:text-indigo-400 rounded"
                        >
                          全选
                        </button>
                        <button
                          onClick={() => setSelectedDocuments([])}
                          className="flex-1 px-2 py-1 text-xs bg-gray-500/10 hover:bg-gray-500/20 text-gray-600 dark:text-gray-400 rounded"
                        >
                          清空
                        </button>
                      </div>
                    </div>
                    
                    {/* 文档列表 */}
                    <div className="max-h-64 overflow-y-auto space-y-1">
                      {documents
                        .filter((doc: any) => {
                          const matchesSearch = docSearchQuery === '' || doc.title.toLowerCase().includes(docSearchQuery.toLowerCase());
                          const matchesKB = docFilterKB === 'all' || doc.knowledge_base_id === docFilterKB;
                          return matchesSearch && matchesKB;
                        })
                        .map((doc: any) => (
                          <label
                            key={doc.id}
                            className="flex items-center gap-2 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-white/10 cursor-pointer"
                          >
                            <input
                              type="checkbox"
                              checked={selectedDocuments.includes(doc.id)}
                              onChange={(e) => {
                                if (e.target.checked) {
                                  setSelectedDocuments([...selectedDocuments, doc.id]);
                                } else {
                                  setSelectedDocuments(selectedDocuments.filter(id => id !== doc.id));
                                }
                              }}
                              className="w-4 h-4 text-indigo-500 rounded focus:ring-2 focus:ring-indigo-500/40"
                            />
                            <div className="flex-1 min-w-0">
                              <p className="text-sm text-gray-700 dark:text-white/90 truncate">{doc.title}</p>
                              <p className="text-xs text-gray-500 dark:text-white/50">
                                {doc.knowledge_base_name || '未分类'} • {doc.word_count || 0} 字
                              </p>
                            </div>
                          </label>
                        ))}
                      {documents.filter((doc: any) => {
                        const matchesSearch = docSearchQuery === '' || doc.title.toLowerCase().includes(docSearchQuery.toLowerCase());
                        const matchesKB = docFilterKB === 'all' || doc.knowledge_base_id === docFilterKB;
                        return matchesSearch && matchesKB;
                      }).length === 0 && (
                        <p className="text-sm text-gray-500 dark:text-white/50 text-center py-4">
                          没有匹配的文档
                        </p>
                      )}
                    </div>
                  </>
                ))}
              </div>
            )}
          </div>

          {/* 消息区域 */}
          <div className="flex-1 overflow-y-auto p-4 space-y-4">
            {messages.length === 0 ? (
              <div className="flex flex-col items-center justify-center h-full text-center">
                <MessageSquare className="h-16 w-16 text-gray-400 dark:text-white/40 mb-4" />
                <h3 className="text-lg font-semibold text-gray-700 dark:text-white/80 mb-2">
                  开始新对话
                </h3>
                <p className="text-sm text-gray-500 dark:text-white/60">
                  选择知识库，输入问题，开始智能问答
                </p>
              </div>
            ) : (
              messages.map((message, index) => (
                <div
                  key={index}
                  className={`flex gap-3 ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
                >
                  {message.role === 'assistant' && (
                    <div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-br from-indigo-500 to-purple-500 flex items-center justify-center">
                      <Bot className="h-5 w-5 text-white" />
                    </div>
                  )}
                  
                  <div className={`max-w-3xl ${message.role === 'user' ? 'order-1' : ''}`}>
                    <div
                      className={`rounded-2xl px-4 py-3 relative group ${
                        message.role === 'user'
                          ? 'bg-gradient-to-r from-indigo-500 to-purple-500 text-white'
                          : 'bg-white/60 dark:bg-white/10 text-gray-900 dark:text-white border border-gray-200/40 dark:border-white/20'
                      }`}
                    >
                      <div className="text-sm prose prose-sm dark:prose-invert max-w-none">
                        <ReactMarkdown remarkPlugins={[remarkGfm]}>
                          {message.content}
                        </ReactMarkdown>
                      </div>
                      
                      {/* 复制和记笔记按钮（仅 AI 回答显示） */}
                      {message.role === 'assistant' && (
                        <div className="absolute top-2 right-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
                          <button
                            onClick={() => copyToClipboard(message.content, index)}
                            className="p-1.5 rounded-lg bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-gray-200/50 dark:border-white/20"
                            title="复制回答"
                          >
                            {copiedIndex === index ? (
                              <Check className="h-4 w-4 text-green-500" />
                            ) : (
                              <Copy className="h-4 w-4 text-gray-600 dark:text-gray-300" />
                            )}
                          </button>
                          <div className="relative">
                            <button
                              onClick={() => setShowSaveNoteMenu(showSaveNoteMenu === index ? null : index)}
                              className="p-1.5 rounded-lg bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-gray-200/50 dark:border-white/20"
                              title="记笔记"
                            >
                              <BookmarkPlus className="h-4 w-4 text-blue-600 dark:text-blue-400" />
                            </button>
                            
                            {/* 记笔记快捷菜单 */}
                            {showSaveNoteMenu === index && (
                              <>
                                <div
                                  className="fixed inset-0 z-40"
                                  onClick={() => setShowSaveNoteMenu(null)}
                                />
                                <div className="absolute right-0 top-full mt-2 w-64 bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200/40 dark:border-white/20 z-50 overflow-hidden">
                                  <div className="p-2">
                                    <button
                                      onClick={() => saveToNewNote(message)}
                                      disabled={savingNote}
                                      className="w-full text-left px-3 py-2 text-sm text-gray-700 dark:text-white hover:bg-blue-50 dark:hover:bg-blue-500/20 rounded-lg flex items-center gap-2"
                                    >
                                      <Plus className="h-4 w-4" />
                                      保存到新笔记
                                    </button>
                                    
                                    {myNotes.length > 0 && (
                                      <>
                                        <div className="my-2 border-t border-gray-200/40 dark:border-white/20" />
                                        <div className="text-xs text-gray-500 dark:text-white/50 px-3 py-1">
                                          追加到已有笔记
                                        </div>
                                        <div className="max-h-48 overflow-y-auto">
                                          {myNotes.slice(0, 5).map((note) => (
                                            <button
                                              key={note.id}
                                              onClick={() => saveToExistingNote(message, note.id)}
                                              disabled={savingNote}
                                              className="w-full text-left px-3 py-2 text-sm text-gray-700 dark:text-white hover:bg-gray-50 dark:hover:bg-white/5 rounded-lg"
                                            >
                                              <div className="truncate">{note.title}</div>
                                            </button>
                                          ))}
                                        </div>
                                      </>
                                    )}
                                  </div>
                                </div>
                              </>
                            )}
                          </div>
                        </div>
                      )}
                    </div>
                    <p className="text-xs text-gray-500 dark:text-white/50 mt-1 px-2">
                      {message.timestamp.toLocaleTimeString('zh-CN')}
                    </p>

                    {message.role === 'assistant' && message.sources && message.sources.length > 0 && (() => {
                      // 按文档分组
                      const groupedSources = message.sources.reduce((acc: any, source: any) => {
                        const docId = source.document_id;
                        if (!acc[docId]) {
                          acc[docId] = {
                            title: source.document_title,
                            chunks: []
                          };
                        }
                        acc[docId].chunks.push(source);
                        return acc;
                      }, {});
                      
                      const uniqueDocs = Object.values(groupedSources);
                      
                      return (
                        <div className="mt-2 p-3 bg-blue-50/50 dark:bg-blue-900/10 rounded-lg border border-blue-200/30 dark:border-blue-500/20">
                          <button
                            onClick={() => {
                              const newExpanded = new Set(expandedSources);
                              if (newExpanded.has(index)) {
                                newExpanded.delete(index);
                              } else {
                                newExpanded.add(index);
                              }
                              setExpandedSources(newExpanded);
                            }}
                            className="w-full text-left text-xs font-semibold text-blue-700 dark:text-blue-300 mb-2 hover:text-blue-800 dark:hover:text-blue-200 transition-colors flex items-center justify-between"
                          >
                            <span>📚 参考文档 ({uniqueDocs.length} 个文档)</span>
                            <span className="text-blue-500">
                              {expandedSources.has(index) ? '▼' : '▶'}
                            </span>
                          </button>
                          
                          {expandedSources.has(index) && (
                            <div className="space-y-2">
                              {uniqueDocs.map((doc: any, idx: number) => (
                                <div
                                  key={idx}
                                  className="text-xs bg-white/50 dark:bg-white/5 p-2 rounded border border-blue-200/20 dark:border-blue-500/10"
                                >
                                  <p className="font-medium text-blue-800 dark:text-blue-200 mb-2">
                                    {idx + 1}. {doc.title}
                                  </p>
                                  {doc.chunks.map((chunk: any, chunkIdx: number) => (
                                    <div key={chunkIdx} className="ml-3 mb-2 last:mb-0 pl-2 border-l-2 border-blue-300/30">
                                      <p className="text-gray-600 dark:text-gray-300 text-[11px] mb-1">
                                        相似度: {(chunk.similarity * 100).toFixed(1)}%
                                      </p>
                                      <p className="text-blue-600 dark:text-blue-300 text-[11px]">
                                        {chunk.excerpt}
                                      </p>
                                    </div>
                                  ))}
                                </div>
                              ))}
                            </div>
                          )}
                        </div>
                      );
                    })()}
                  </div>

                  {message.role === 'user' && (
                    <div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-br from-green-500 to-emerald-500 flex items-center justify-center order-2">
                      <User className="h-5 w-5 text-white" />
                    </div>
                  )}
                </div>
              ))
            )}
            <div ref={messagesEndRef} />
          </div>

          {/* 输入区域 */}
          <div className="p-4 border-t border-gray-200/40 dark:border-white/20">
            <div className="flex gap-2">
              <textarea
                ref={inputRef}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    handleSend();
                  }
                }}
                placeholder="输入您的问题... (Shift+Enter换行, Enter发送)"
                className="flex-1 px-4 py-3 bg-white/60 dark:bg-white/10 backdrop-blur-md border border-gray-300/40 dark:border-white/20 rounded-lg text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-indigo-500/40 resize-none"
                rows={3}
                disabled={loading}
              />
              <GlassButton
                onClick={handleSend}
                disabled={!input.trim() || loading}
                variant="primary"
                className="self-end"
              >
                <Send className="h-5 w-5" />
              </GlassButton>
            </div>
          </div>
        </GlassCard>
      </div>

      {/* 删除确认对话框 */}
      {showDeleteConfirm && deleteTarget && (
        <>
          {/* 背景遮罩 */}
          <div 
            className="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center"
            onClick={() => setShowDeleteConfirm(false)}
          >
            {/* 对话框 */}
            <div 
              className="glass rounded-3xl shadow-2xl max-w-md w-full mx-4 overflow-hidden border border-red-200/40 dark:border-red-500/30"
              onClick={(e) => e.stopPropagation()}
            >
              {/* 顶部装饰 */}
              <div className="h-2 bg-gradient-to-r from-red-500 via-pink-500 to-red-500"></div>
              
              {/* 内容区 */}
              <div className="p-8">
                {/* 图标 */}
                <div className="flex justify-center mb-6">
                  <div className="w-16 h-16 rounded-full bg-gradient-to-br from-red-100 to-pink-100 dark:from-red-500/20 dark:to-pink-500/20 flex items-center justify-center">
                    <Trash2 className="h-8 w-8 text-red-500 dark:text-red-400" />
                  </div>
                </div>

                {/* 标题 */}
                <h3 className="text-xl font-bold text-center text-gray-900 dark:text-white mb-3">
                  确认删除对话
                </h3>

                {/* 对话标题 */}
                <div className="bg-gradient-to-r from-red-50/80 to-pink-50/80 dark:from-red-500/10 dark:to-pink-500/10 rounded-xl p-4 mb-6">
                  <p className="text-sm text-gray-600 dark:text-white/70 mb-2 text-center">
                    即将删除以下对话：
                  </p>
                  <p className="text-center font-semibold text-gray-900 dark:text-white break-all">
                    {deleteTarget.title}
                  </p>
                </div>

                {/* 警告信息 */}
                <div className="bg-yellow-50/80 dark:bg-yellow-500/10 border border-yellow-200/50 dark:border-yellow-500/30 rounded-xl p-4 mb-6">
                  <p className="text-sm text-yellow-800 dark:text-yellow-200 text-center">
                    ⚠️ 此操作不可恢复，对话历史记录将被永久删除
                  </p>
                </div>

                {/* 按钮组 */}
                <div className="flex gap-3">
                  <GlassButton
                    onClick={() => setShowDeleteConfirm(false)}
                    variant="secondary"
                    className="flex-1 py-3"
                  >
                    取消
                  </GlassButton>
                  <GlassButton
                    onClick={deleteSession}
                    className="flex-1 py-3 bg-gradient-to-r from-red-500 to-pink-500 hover:from-red-600 hover:to-pink-600 text-white"
                  >
                    确认删除
                  </GlassButton>
                </div>
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}
